#include "StdAfx.h"
#include "ActivityMediator.h"

#include "UtGenerator.h"
#include "TestRunnerWnd.h"

CActivityMediator::CActivityMediator(void) : 
	m_pTestRunnerWnd(NULL),
	m_bSwitchToOutput(TRUE)
{
}

CActivityMediator::~CActivityMediator(void)
{
	
}

void CActivityMediator::Init(EnvDTE80::DTE2 *pDTE, EnvDTE::AddIn *pAddInInstance)
{
	m_spDTE = pDTE;
	m_spAddInInstance = pAddInInstance;
}

void CActivityMediator::TestWizard()
{
	CUtGenerator cs;
	if ((cs.GenerateTests(m_spDTE)) && (m_pTestRunnerWnd))
	{
		m_pTestRunnerWnd->SetTimer(IDC_BT_REFRESH, 100);
	}
}

void CActivityMediator::ShowTestRunnerWnd()
{
	ATLASSERT(m_spDTE);
	ATLASSERT(m_spAddInInstance);

	if (m_spWindow)
	{
		m_spWindow->Activate();
		m_spWindow->put_Visible(VARIANT_TRUE);
	}
	else
	{	//First launch
		IDispatchPtr spDispatch;
		EnvDTE::WindowsPtr	spWindows;
		CComPtr<ITestRunnerWnd> spTestRunnerWnd;

#ifdef _VS2008
		CComBSTR bstrProdId(L"Cput.TestRunnerWnd2008");
		CComBSTR bstrGuidPos(L"{7841FB11-113C-4522-91E7-8CFFB12109B2}");
#else
		CComBSTR bstrProdId(L"Cput.TestRunnerWnd");
		CComBSTR bstrGuidPos(L"{7841FB11-113C-4522-91E7-8CFFB12109B2}");
#endif
		
		if ((m_spDTE) && (m_spAddInInstance) &&
			SUCCEEDED(m_spDTE->get_Windows(&spWindows)) &&
			SUCCEEDED(spWindows->CreateToolWindow(m_spAddInInstance, bstrProdId, CComBSTR(L"Test Runner"), bstrGuidPos, &spDispatch, &m_spWindow)) &&
			SUCCEEDED(spDispatch->QueryInterface(IID_ITestRunnerWnd, (void**)&spTestRunnerWnd)) &&
			(m_pTestRunnerWnd = (CTestRunnerWnd*)spTestRunnerWnd.p))

		{
			m_csTestAppRunNotification.Init(m_pTestRunnerWnd);
			m_pTestRunnerWnd->Prepare(m_spDTE, this);
			m_spWindow->put_Visible(VARIANT_TRUE);

			m_hTabBmp = LoadBitmap(_AtlModule.GetResourceInstance(), MAKEINTRESOURCE(IDB_TESTRUNNERTAB));
			PICTDESC sPictDesc;
			sPictDesc.cbSizeofstruct = sizeof(sPictDesc);
			sPictDesc.picType = PICTYPE_BITMAP;
			sPictDesc.bmp.hbitmap = m_hTabBmp;
			sPictDesc.bmp.hpal = NULL;

			IPictureDispPtr spPicture;
			CComVariant vt;
			vt.vt = VT_DISPATCH;

			if (SUCCEEDED(OleCreatePictureIndirect(&sPictDesc, IID_IPictureDisp, FALSE, (void**)&spPicture)) &&
				SUCCEEDED(spPicture.QueryInterface(IID_IDispatch, (void**)&vt.pdispVal)))
			{
				m_spWindow->SetTabPicture(vt);
			}

			m_csSolutionEventHandler.Advise(m_spDTE, this);
			m_csDebuggerEventHandler.Advise(m_spDTE, this);
			m_csBuildEventHandler.Advise(m_spDTE, this);
		}
	}
}

void CActivityMediator::Dispose()
{
	m_csSolutionEventHandler.UnAdvise();
	m_csDebuggerEventHandler.UnAdvise();
	m_csBuildEventHandler.UnAdvise();

	m_csTestAppRunNotification.Dispose();

	if (m_spWindow)
	{
		m_spWindow->Close(EnvDTE::vsSaveChangesNo);
	}
	m_spWindow = NULL;
	m_pTestRunnerWnd = NULL;
	DeleteObject(m_hTabBmp); //validation check is inside

	m_spDTE = NULL;
	m_spAddInInstance = NULL;
}

//ISolutionEventHandler methods
void CActivityMediator::Opened()
{
	if (m_pTestRunnerWnd)
	{
		m_pTestRunnerWnd->SetTimer(IDC_BT_REFRESH, 100);
	}
}

void CActivityMediator::BeforeClosing()
{
}

void CActivityMediator::AfterClosing()
{
	if (m_pTestRunnerWnd)
	{
		m_pTestRunnerWnd->SetTimer(IDC_BT_REFRESH, 100);
	}
}

void CActivityMediator::QueryCloseSolution(VARIANT_BOOL* fCancel)
{
}

void CActivityMediator::Renamed(BSTR OldName)
{
	if (m_pTestRunnerWnd)
	{
		m_pTestRunnerWnd->SetTimer(IDC_BT_REFRESH, 100);
	}
}

void CActivityMediator::ProjectAdded(EnvDTE::Project* Project)
{
	if (m_pTestRunnerWnd)
	{
		m_pTestRunnerWnd->SetTimer(IDC_BT_REFRESH, 100);
	}
}

void CActivityMediator::ProjectRemoved(EnvDTE::Project* Project)
{
	if (m_pTestRunnerWnd)
	{
		m_pTestRunnerWnd->SetTimer(IDC_BT_REFRESH, 100);
	}
}

void CActivityMediator::ProjectRenamed(EnvDTE::Project* Project, BSTR OldName)
{
	if (m_pTestRunnerWnd)
	{
		m_pTestRunnerWnd->SetTimer(IDC_BT_REFRESH, 100);
	}
}

//IDebuggerEventHandler methods
void CActivityMediator::ContextChanged(EnvDTE::Process* pProcess , EnvDTE::Program* pProgram, EnvDTE::Thread* pThread, EnvDTE::StackFrame* pStackFrame)
{
}

void CActivityMediator::EnterBreakMode(EnvDTE::dbgEventReason dbgEventReason, EnvDTE::dbgExecutionAction* pdbgExecutionAction)
{
}

void CActivityMediator::EnterDesignMode(EnvDTE::dbgEventReason dbgEventReason)
{
	if ((dbgEventReason == EnvDTE::dbgEventReasonEndProgram) ||
		(dbgEventReason == EnvDTE::dbgEventReasonStopDebugging))
	{
		EnvDTE::_SolutionPtr spSolution;
		EnvDTE::SolutionBuildPtr spSolutionBuild;

		if ((m_vtPrevStartupProj.vt == VT_BSTR) &&
			SUCCEEDED(m_spDTE->get_Solution(&spSolution)) &&
			(spSolution) &&
			SUCCEEDED(spSolution->get_SolutionBuild(&spSolutionBuild)) &&
			(spSolutionBuild))
		{
			spSolutionBuild->put_StartupProjects(m_vtPrevStartupProj);
		}
	}
}

void CActivityMediator::EnterRunMode(EnvDTE::dbgEventReason dbgEventReason)
{
}

void CActivityMediator::ExceptionNotHandled(BSTR bstrExceptionType, BSTR bstrName, int nCode, BSTR bstrDescription, EnvDTE::dbgExecutionAction* pdbgExecutionAction)
{
}

void CActivityMediator::ExceptionThrown(BSTR bstrExceptionType, BSTR bstrName, int nCode, BSTR bstrDescription, EnvDTE::dbgExecutionAction* pdbgExecutionAction)
{
}

void CActivityMediator::OnBuildBegin(EnvDTE::vsBuildScope Scope, EnvDTE::vsBuildAction Action)
{
}

void CActivityMediator::OnBuildDone(EnvDTE::vsBuildScope Scope, EnvDTE::vsBuildAction Action)
{
}

void CActivityMediator::OnBuildProjConfigBegin(BSTR Project, BSTR ProjectConfig, BSTR Platform, BSTR SolutionConfig)
{
	if (m_bSwitchToOutput)
	{
		m_bSwitchToOutput = FALSE;
		//switch to the output window
		EnvDTE80::ToolWindowsPtr spToolWindows;
		EnvDTE::OutputWindowPtr spOutputWindow;
		EnvDTE::OutputWindowPanePtr spOutputWindowPane;
		EnvDTE::WindowPtr spWindow;
		if (SUCCEEDED(m_spDTE->get_ToolWindows(&spToolWindows)) && (spToolWindows) &&
			SUCCEEDED(spToolWindows->get_OutputWindow(&spOutputWindow)) && (spOutputWindow) &&
			SUCCEEDED(spOutputWindow->get_ActivePane(&spOutputWindowPane)) && (spOutputWindowPane) &&
			SUCCEEDED(spOutputWindow->get_Parent(&spWindow)) && (spWindow) &&
			SUCCEEDED(spWindow->get_AutoHides(&m_vbOutputHideStatus)))
		{
			spWindow->put_AutoHides(VARIANT_FALSE);
			spWindow->Activate();
		}
	}
}

void CActivityMediator::OnBuildProjConfigDone(BSTR Project, BSTR ProjectConfig, BSTR Platform, BSTR SolutionConfig, VARIANT_BOOL Success)
{
}

void CActivityMediator::TestAppNotify(WPARAM wParam, LPARAM lParam)
{
	m_csTestAppRunNotification.TestAppNotify(wParam, lParam);
}

void CActivityMediator::Start(EnvDTE::Project* pCurSelProject, BOOL bDebug)
{
	m_bSwitchToOutput = TRUE;

	EnvDTE::ProjectPtr spCurSelProject;
	CComVariant vtUniqueName;
	EnvDTE::_SolutionPtr spSolution;
	EnvDTE::SolutionBuildPtr spSolutionBuild;
	CComBSTR bstrActConfName;
	EnvDTE::SolutionConfigurationPtr spActConf;
	long nFailedProj;
	
	vtUniqueName.vt = VT_BSTR;

	if (SUCCEEDED(pCurSelProject->get_UniqueName(&vtUniqueName.bstrVal)) &&
		SUCCEEDED(m_spDTE->get_Solution(&spSolution)) &&
		(spSolution) &&
		SUCCEEDED(spSolution->get_SolutionBuild(&spSolutionBuild)) &&
		(spSolutionBuild) &&
		SUCCEEDED(spSolutionBuild->get_StartupProjects(&m_vtPrevStartupProj)) &&
		SUCCEEDED(spSolutionBuild->put_StartupProjects(vtUniqueName)) &&
		SUCCEEDED(spSolutionBuild->get_ActiveConfiguration(&spActConf)) &&
		SUCCEEDED(spActConf->get_Name(&bstrActConfName)) &&
		SUCCEEDED(spSolutionBuild->BuildProject(bstrActConfName, vtUniqueName.bstrVal, VARIANT_TRUE)) &&
		SUCCEEDED(spSolutionBuild->get_LastBuildInfo(&nFailedProj))
		)
	{
		if (nFailedProj)
		{
			EnvDTE80::ToolWindowsPtr spToolWindows;
			EnvDTE80::ErrorListPtr spErrorList;
			EnvDTE::WindowPtr spWindow;
			if (SUCCEEDED(m_spDTE->get_ToolWindows(&spToolWindows)) &&
				SUCCEEDED(spToolWindows->get_ErrorList(&spErrorList)) &&
				SUCCEEDED(spErrorList->get_Parent(&spWindow)))
			{
				spWindow->Activate();
				spWindow->put_AutoHides(VARIANT_FALSE);
			}
		} 
		else
		{
			EnvDTE80::ToolWindowsPtr spToolWindows;
			EnvDTE::OutputWindowPtr spOutputWindow;
			EnvDTE::OutputWindowPanePtr spOutputWindowPane;
			EnvDTE::WindowPtr spWindow;
			
			if (SUCCEEDED(m_spDTE->get_ToolWindows(&spToolWindows)) && (spToolWindows) &&
				SUCCEEDED(spToolWindows->get_OutputWindow(&spOutputWindow)) && (spOutputWindow) &&
				SUCCEEDED(spOutputWindow->get_ActivePane(&spOutputWindowPane)) && (spOutputWindowPane) &&
				SUCCEEDED(spOutputWindow->get_Parent(&spWindow)) && (spWindow))
			{
				spWindow->put_AutoHides(m_vbOutputHideStatus);
			}

			if (bDebug)
			{
				spSolutionBuild->Debug();
			}
			else
			{
				spSolutionBuild->Run();
			}
		}
	}
}

